(function () {
    function $(select) {
        return document.querySelector(select);
    }

    // 游戏常量
    const HUMAN = 'human';
    const AI = 'ai';
    const MAX_THINKING_TIME = 10000;
    
    var chessContainer = $('.container'),
        tableContainer = $('.container-content'),
        isGameOver = false,
        chessColor = 'black',
        moveCount = 0,
        board = Array.from({ length: 14 }, () => Array(14).fill(null)),
        startBtn = $('#start-btn'),
        gameSelect = $('#game-select'),
        colorSelect = $('#color-select'),
        currentPlayer = HUMAN,
        humanColor = 'black',
        aiColor = 'white',
        thinking = false;

    var endChessColor = 'white';
    var endElement = {
        containerEnd: $('.container-end'),
        endContainerColor: $('.end-container-color'),
        endYes: $('.end-yes'),
        endNo: $('.end-no')
    };
    var chessArr = [];

    // 更新按钮文字
    function updateButtonText() {
        startBtn.textContent = chessArr.length > 0 ? '重新开始' : '开始游戏';
    }

    // 创建14x14棋盘
    function createTbody() {
        var tableContent = "";
        for (let i = 0; i < 14; i++) {
            var tdText = "<tr>";
            for (let j = 0; j < 14; j++) {
                tdText += `<td data-row='${i}' data-line='${j}'></td>`;
            }
            tdText += "</tr>";
            tableContent += tdText;
        }
        tableContainer.innerHTML = tableContent;
    }

    function isRecur(x, y) {
        return board[y][x] === null;
    }

    // 检查五子连珠胜利条件
    function checkWin(row, col, color) {
        const directions = [[0,1],[1,0],[1,1],[1,-1]];
        return directions.some(([dx, dy]) => {
            let count = 1;

            for (let i = 1; i < 5; i++) {
                const r = row + dx * i;
                const c = col + dy * i;
                if (r < 0 || r >= 14 || c < 0 || c >= 14 || board[r][c]?.color !== color) break;
                count++;
            }

            for (let i = 1; i < 5; i++) {
                const r = row - dx * i;
                const c = col - dy * i;
                if (r < 0 || r >= 14 || c < 0 || c >= 14 || board[r][c]?.color !== color) break;
                count++;
            }

            if (count >= 5) {
                highlightWinningLine(row, col, dx, dy, color);
                isGameOver = true;
                endChessColor = color;
                showMoveNumbers();
                updateStats(); // 更新统计数据
                return true;
            }
            return false;
        });
    }

    function highlightWinningLine(row, col, dx, dy, color) {
        const positions = [];
        for (let i = -4; i <= 4; i++) {
            const r = row + dx * i;
            const c = col + dy * i;
            if (r >= 0 && r < 14 && c >= 0 && c < 14 && board[r][c]?.color === color) {
                positions.push({ x: c, y: r });
            }
        }

        positions.forEach(({x, y}) => {
            $(`div[data-row="${y}"][data-line="${x}"]`).classList.add('win');
        });
    }

    // 在棋子上显示落子顺序
    function showMoveNumbers() {
        chessArr.forEach(({x, y, move}) => {
            const chess = $(`td[data-row="${y}"][data-line="${x}"]`)?.querySelector('.chess');
            chess && (chess.textContent = move);
        });
    }

    // 重置游戏
    function resetGame() {
        endElement.containerEnd.style.display = 'none';
        board = Array.from({ length: 14 }, () => Array(14).fill(null));
        chessArr = [];
        moveCount = 0;
        createTbody();
        isGameOver = false;
        
        // 设置玩家和AI颜色
        humanColor = colorSelect.value;
        aiColor = humanColor === 'black' ? 'white' : 'black';
        
        // 总是黑棋先手
        chessColor = 'black';
        currentPlayer = 'black' === humanColor ? HUMAN : AI;
        
        // 根据游戏模式设置
        if (gameSelect.value === 'pve') {
            // 人机对战模式
            colorSelect.disabled = false;
            
            // 强制下一帧执行，确保DOM更新完成
            requestAnimationFrame(() => {
                // 如果是AI回合，让AI走棋
                if (currentPlayer === AI) {
                    makeAIMove();
                }
            });
        } else {
            // 双人对战模式
            colorSelect.disabled = true;
            currentPlayer = HUMAN;
        }
        
        updateButtonText();
    }



    // 评估棋盘状态
    function evaluateBoard() {
        let score = 0;
        const directions = [[0,1],[1,0],[1,1],[1,-1]];
        
        for (let y = 0; y < 14; y++) {
            for (let x = 0; x < 14; x++) {
                if (board[y][x] === null) continue;
                
                for (const [dx, dy] of directions) {
                    if (x + dx*4 >= 14 || y + dy*4 >= 14 || y + dy*4 < 0) continue;
                    
                    const line = [];
                    for (let i = 0; i < 5; i++) {
                        const cell = board[y + dy*i][x + dx*i];
                        line.push(cell ? cell.color : null);
                    }
                    
                    score += evaluateLine(line, aiColor);
                }
            }
        }
        return score;
    }

    // 评估一行棋子的分数
    function evaluateLine(line, player) {
        const opponent = player === 'black' ? 'white' : 'black';
        let playerCount = 0, opponentCount = 0, emptyCount = 0;
         
        for (const cell of line) {
            if (cell === player) playerCount++;
            else if (cell === opponent) opponentCount++;
            else emptyCount++;
        }
         
        if (playerCount > 0 && opponentCount > 0) return 0;
         
        // 评分规则
        if (playerCount === 5) return 1000000;
        if (opponentCount === 5) return -1000000;
        if (opponentCount === 4 && emptyCount === 1) return -500000;
        if (playerCount === 4 && emptyCount === 1) return 100000;
        if (opponentCount === 3 && emptyCount === 2) return -50000;
        if (playerCount === 3 && emptyCount === 2) return 10000;
        if (playerCount === 2 && emptyCount === 3) return 1000;
        if (opponentCount === 2 && emptyCount === 3) return -1000;
        if (playerCount === 1 && emptyCount === 4) return 10;
        if (opponentCount === 1 && emptyCount === 4) return -10;
         
        return 0;
    }

    // 极大极小算法
    function minimax(depth, alpha, beta, isMaximizing, startTime) {
        // 终止条件
        if (depth === 0 || isGameOver || Date.now() - startTime > MAX_THINKING_TIME - 100) {
            return evaluateBoard();
        }
        
        if (isMaximizing) {
            let maxScore = -Infinity;
            const moves = getPossibleMoves();
            
            for (const move of moves) {
                board[move.y][move.x] = { color: aiColor };
                const score = minimax(depth-1, alpha, beta, false, startTime);
                board[move.y][move.x] = null;
                
                maxScore = Math.max(maxScore, score);
                alpha = Math.max(alpha, score);
                if (beta <= alpha) break; // Alpha-Beta剪枝
            }
            return maxScore;
        } else {
            let minScore = Infinity;
            const moves = getPossibleMoves();
            
            for (const move of moves) {
                board[move.y][move.x] = { color: humanColor };
                const score = minimax(depth-1, alpha, beta, true, startTime);
                board[move.y][move.x] = null;
                
                minScore = Math.min(minScore, score);
                beta = Math.min(beta, score);
                if (beta <= alpha) break; // Alpha-Beta剪枝
            }
            return minScore;
        }
    }

    // 8方向向量: 上,下,左,右,4个对角线
    const DIRECTIONS = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];

    // 获取有效落子位置(优先考虑已有棋子周围)
    function getPossibleMoves() {
        const moves = [];
        const considered = Array(14).fill().map(() => Array(14).fill(false));
        
        for (let y = 0; y < 14; y++) {
            for (let x = 0; x < 14; x++) {
                if (board[y][x] !== null) {
                    for (const [dy, dx] of DIRECTIONS) {
                        const ny = y + dy, nx = x + dx;
                        if (ny >= 0 && ny < 14 && nx >= 0 && nx < 14 && 
                            board[ny][nx] === null && !considered[ny][nx]) {
                            moves.push({x: nx, y: ny});
                            considered[ny][nx] = true;
                        }
                    }
                }
            }
        }
        
        // 保底: 若无候选位置则返回所有空位
        return moves.length ? moves : getAllEmptyPositions();
    }

    function getAllEmptyPositions() {
        const moves = [];
        for (let y = 0; y < 14; y++) {
            for (let x = 0; x < 14; x++) {
                if (board[y][x] === null) moves.push({x, y});
            }
        }
        return moves;
    }

    // AI决策主逻辑
    function makeAIMove() {
        if (isGameOver || thinking || gameSelect.value !== 'pve') return;
        
        console.log('AI开始思考...');
        setTimeout(() => {
            thinking = true;
            const startTime = Date.now();
            let bestMove = {x: 7, y: 7};
            let bestScore = -Infinity;
            const possibleMoves = getPossibleMoves();
            
            if (!possibleMoves.length) {
                console.log('AI: 无有效落子位置');
                thinking = false;
                return;
            }
            
            for (const move of possibleMoves) {
                if (Date.now() - startTime > MAX_THINKING_TIME - 100) {
                    console.log('AI思考超时，使用当前最佳走法');
                    break;
                }
                
                board[move.y][move.x] = { color: aiColor };
                const score = minimax(3, -Infinity, Infinity, false, startTime);
                board[move.y][move.x] = null;
                
                if (score > bestScore) {
                    bestScore = score;
                    bestMove = move;
                }
            }
            
            console.log(`AI决定下在: (${bestMove.x},${bestMove.y})，得分: ${bestScore}`);
            executeAIMove(bestMove);
        }, 300);
    }

    // 移除所有棋子的最新落子标记
    function clearLastMoveHighlight() {
        document.querySelectorAll('.chess.last-move').forEach(el => {
            el.classList.remove('last-move');
        });
    }

    function executeAIMove(move) {
        chessColor = aiColor;
        board[move.y][move.x] = { color: aiColor, move: ++moveCount };
        const cell = $(`td[data-row="${move.y}"][data-line="${move.x}"]`);
        clearLastMoveHighlight();
        cell.innerHTML = `<div class="chess ${aiColor} last-move" data-row="${move.y}" data-line="${move.x}" data-move="${moveCount}"></div>`;
        chessArr.push({ x: move.x, y: move.y, c: aiColor, move: moveCount });
        
        if (!checkWin(move.y, move.x, aiColor)) {
            currentPlayer = HUMAN;
            chessColor = humanColor;
        }
        
        thinking = false;
        updateButtonText();
    }

    // 处理棋盘点击事件
    function onTableClick() {
        chessContainer.addEventListener('click', function(e) {
            // 处理AI回合禁止操作
            if (gameSelect.value === 'pve' && currentPlayer !== HUMAN) {
                console.log('AI回合禁止操作');
                return;
            }
            
            // 处理游戏进行中的点击
            if (!isGameOver && e.target.nodeName === 'TD') {
                const {row, line} = e.target.dataset;
                const tdw = tableContainer.clientWidth / 14;
                const x = e.offsetX > tdw/2 ? parseInt(line)+1 : parseInt(line);
                const y = e.offsetY > tdw/2 ? parseInt(row)+1 : parseInt(row);

                if (x < 14 && y < 14 && isRecur(x, y)) {
                    // 处理玩家落子
                    board[y][x] = { color: chessColor, move: ++moveCount };
                    const cell = $(`td[data-row="${y}"][data-line="${x}"]`);
                    clearLastMoveHighlight();
                    cell.innerHTML = `<div class="chess ${chessColor} last-move" data-row="${y}" data-line="${x}" data-move="${moveCount}"></div>`;
                    chessArr.push({ x, y, c: chessColor, move: moveCount });
                    
                    // 检查胜利条件
                    if (!checkWin(y, x, chessColor)) {
                        // 根据游戏模式切换回合
                        if (gameSelect.value === 'pve') {
                            currentPlayer = AI;
                            chessColor = aiColor;
                            makeAIMove();
                        } else {
                            chessColor = chessColor === 'black' ? 'white' : 'black';
                        }
                    }
                    
                    updateButtonText();
                }
            } 
            // 处理游戏结束后的点击
            else if (isGameOver && e.target.nodeName === 'TD') {
                if (endElement.containerEnd.style.display !== 'block') {
                    endElement.containerEnd.style.display = 'block';
                    endElement.endContainerColor.style.color = endChessColor;
                    endElement.endContainerColor.innerHTML = endChessColor === 'white' ? '白棋' : '黑棋';
                }
            }
        });
    }
    
    // 保存当前游戏状态到localStorage
    function saveGameState() {
        localStorage.setItem('gobang_save', JSON.stringify({
            board, currentPlayer, chessColor, humanColor, aiColor,
            moveCount, chessArr, isGameOver,
            gameMode: gameSelect.value,
            playerColor: colorSelect.value
        }));
        console.log('游戏状态已保存');
    }

    // 从localStorage加载游戏状态
    function loadGameState() {
        try {
            const data = localStorage.getItem('gobang_save');
            if (!data) {
                console.log('没有找到保存的游戏');
                return false;
            }

            const {board: b, chessArr: a, ...state} = JSON.parse(data);
            
            // 恢复游戏状态
            Object.assign(this, state);
            board = b;
            chessArr = a;
            
            // 恢复UI状态
            gameSelect.value = state.gameMode;
            colorSelect.value = state.playerColor;
            createTbody();
            
            // 重新渲染棋子
            a.forEach(item => {
                $(`td[data-row="${item.y}"][data-line="${item.x}"]`)
                    .innerHTML = `<div class="chess ${item.c}" data-row="${item.y}" data-line="${item.x}" data-move="${item.move}"></div>`;
            });
            
            updateButtonText();
            console.log('游戏状态已加载');
            return true;
        } catch (e) {
            console.error('加载游戏状态失败:', e);
            return false;
        }
    }

    // 初始化事件
    function initEvent() {
        endElement.endYes.addEventListener('click', resetGame);
        endElement.endNo.addEventListener('click', function () {
            endElement.containerEnd.style.display = 'none';
        });

        // 开始/重新开始按钮点击事件
        startBtn.addEventListener('click', resetGame);

        // 游戏模式切换事件
        gameSelect.addEventListener('change', function() {
            console.log(`游戏模式切换: ${this.value}`);
            resetGame();
        });
        
        // 使用HTML中已有的保存/加载按钮
        $('#save-btn').addEventListener('click', saveGameState);
        $('#load-btn').addEventListener('click', loadGameState);
        
        // 棋盘点击事件
        chessContainer.addEventListener('click', function(e) {
            if (gameSelect.value === 'pve' && currentPlayer !== HUMAN) return;
        });
    }

    // 更新统计数据
    function updateStats() {
        // 统计棋子数量
        let blackCount = chessArr.filter(c => c.c === 'black').length;
        let whiteCount = chessArr.filter(c => c.c === 'white').length;
        
        // 更新棋子数量图表
        window.gobangCharts.countChart.setOption({
            series: [{
                data: [
                    { value: blackCount, name: '黑棋' },
                    { value: whiteCount, name: '白棋' }
                ]
            }]
        });

        // 获取历史胜率数据
        let stats = JSON.parse(localStorage.getItem('gobang_stats') || '{"blackWins":0,"whiteWins":0}');
        
        // 更新当前胜局
        if (endChessColor === 'black') stats.blackWins++;
        else if (endChessColor === 'white') stats.whiteWins++;
        
        // 保存胜率数据
        localStorage.setItem('gobang_stats', JSON.stringify(stats));
        
        // 计算胜率百分比
        const total = stats.blackWins + stats.whiteWins;
        const blackRate = total > 0 ? Math.round(stats.blackWins / total * 100) : 0;
        const whiteRate = total > 0 ? Math.round(stats.whiteWins / total * 100) : 0;
        
        // 更新胜率图表
        window.gobangCharts.winRateChart.setOption({
            series: [{
                data: [blackRate, whiteRate]
            }]
        });
    }

    // 初始化图表
    function initCharts() {
        // 棋子数量统计图
        const countChart = echarts.init(document.getElementById('chess-count-chart'));
        countChart.setOption({
            title: { text: '棋子数量统计', left: 'center' },
            tooltip: { trigger: 'item' },
            series: [{
                name: '棋子数量',
                type: 'pie',
                radius: '50%',
                data: [
                    { value: 0, name: '黑棋' },
                    { value: 0, name: '白棋' }
                ],
                emphasis: {
                    itemStyle: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                }
            }]
        });

        // 胜率统计图
        const winRateChart = echarts.init(document.getElementById('win-rate-chart'));
        
        // 初始化胜率数据
        let stats = JSON.parse(localStorage.getItem('gobang_stats') || '{"blackWins":0,"whiteWins":0}');
        const total = stats.blackWins + stats.whiteWins;
        const blackRate = total > 0 ? Math.round(stats.blackWins / total * 100) : 0;
        const whiteRate = total > 0 ? Math.round(stats.whiteWins / total * 100) : 0;
        
        winRateChart.setOption({
            title: { text: '胜率统计', left: 'center' },
            tooltip: { trigger: 'axis' },
            xAxis: { type: 'category', data: ['黑棋', '白棋'] },
            yAxis: { type: 'value', max: 100 },
            series: [{
                name: '胜率',
                type: 'bar',
                data: [blackRate, whiteRate],
                itemStyle: {
                    color: function(params) {
                        return params.dataIndex === 0 ? '#000' : '#fff';
                    },
                    borderColor: '#666',
                    borderWidth: 1
                }
            }]
        });

        return { countChart, winRateChart };
    }

    // 初始化
    function init() {
        createTbody();
        onTableClick();
        initEvent();
        const charts = initCharts();
        
        // 暴露图表实例供更新使用
        window.gobangCharts = charts;
    }

    init();
})();